{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# STRUCTURED TYPES, MUTABILITY\n",
    "\n",
    "The numeric types `int` and `float` are **scalar(标量)** types. That is to say, objects of these types have **no accessible internal structure**. \n",
    "\n",
    "In contrast, `str` can be thought of as a `structured, or non-scalar`, type. One can use indexing to extract individual characters from a string and slicing to extract substrings.\n",
    "\n",
    "In this chapter, we introduce `four additional structured types`. \n",
    "\n",
    "* <b style=\"color:blue\">tuple</b>(元组）, is a rather simple generalization of `str`. \n",
    "\n",
    "* <b style=\"color:blue\">list</b>(列表）\n",
    "\n",
    "* range\n",
    "\n",
    "* <b style=\"color:blue\">dict</b>(字典） —are more **interesting**. \n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1 Tuples\n",
    "\n",
    "Like `strings`, **tuples** are <b style=\"color:blue\">immutable ordered sequences</b> of elements. \n",
    "\n",
    "The difference is that the elements of a tuple need <b style=\"color:blue\">not be characters</b>. The individual elements can be of\n",
    "<b style=\"color:blue\">any type</b>, and need <b style=\"color:blue\">not be of the same type</b> as each other\n",
    "\n",
    "\n",
    "Literals of type `tuple` are written by enclosing a <b style=\"color:blue\">comma-separated ,</b> list of elements <b style=\"color:blue\">within parentheses( )</b>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "()\n",
      "(1, 'two', 3)\n",
      "('Name', 22)\n"
     ]
    }
   ],
   "source": [
    "t1 = () # empty tuple\n",
    "\n",
    "t2 = (1, 'two', 3) #  1）any type; 2） not be of the same type as each other.\n",
    "student=('Name',22)\n",
    "print(t1)\n",
    "print(t2)\n",
    "print(student)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "Looking at this example, you might naturally be led to believe that the tuple containing the `single value 1` would be written `(1)`. But, to quote [Richard Nixon](https://en.wikipedia.org/wiki/Richard_Nixon), `“that would be wrong.”`\n",
    "\n",
    "Since parentheses`( )` are used to `group expressions`,<b  style=\"color:blue\">(1)</b> is `merely` a verbose way to write the `integer 1`. \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a=(1)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3,)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b=(a+2,)\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1,)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a=(1,)\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To denote <b  style=\"color:blue\">the singleton tuple</b> containing this value, we write <strong style=\"color:red\">(1 ,)</strong>\n",
    "\n",
    "**Almost everybody who uses Python has at one time or another accidentally omitted that annoying `comma`.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10+1\n",
      "<class 'str'>\n",
      "\n",
      "The singleton tuple containing this value\n",
      "('10+1',)\n",
      "<class 'tuple'>\n"
     ]
    }
   ],
   "source": [
    "expre=('10+1')\n",
    "\n",
    "tsingleton=('10+1',)  # comma-separated \n",
    "\n",
    "print(expre)\n",
    "print(type(expre))\n",
    "\n",
    "print('\\nThe singleton tuple containing this value')\n",
    "print(tsingleton)\n",
    "print(type(tsingleton))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Repetition** can be used on tuples. For example, the expression `3*('a', 2)` evaluates to `('a', 2, 'a', 2, 'a', 2).`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('a', 2, 'a', 2, 'a', 2)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "3*('a', 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<b>Like string</b> ,Tuples can be <b style=\"color:blue\">concatenated</b>, <b style=\"color:blue\">indexed</b>, and <b style=\"color:blue\">sliced</b>.(indexing <strong style=\"color:blue\">starts at 0</strong>)\n",
    "\n",
    "<b style=\"color:blue\">concatenated</b>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "t2= ((1, 'two', 3), 3.25)\n",
      "t1+t2= (1, 'two', 3, (1, 'two', 3), 3.25)\n"
     ]
    }
   ],
   "source": [
    "t1 = (1, 'two', 3)\n",
    "\n",
    "t2 = (t1, 3.25)   #  any type,tuples can contain tuples\n",
    "\n",
    "print('t2=',t2)\n",
    "\n",
    "print('t1+t2=',t1 + t2)  # + concatenated\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<b style=\"color:blue\">indexed</b>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(t1 + t2)[3]= (1, 'two', 3)\n"
     ]
    }
   ],
   "source": [
    "print('(t1 + t2)[3]=',(t1 + t2)[3]) # [3] indexed tuple :as always in Python, indexing starts at 0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<b style=\"color:blue\">sliced</b>.(indexing <strong style=\"color:blue\">starts at 0</strong>)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(t1 + t2)[2:4]= (3, (1, 'two', 3))\n"
     ]
    }
   ],
   "source": [
    "print('(t1 + t2)[2:4]=',(t1 + t2)[2:4]) # [2:5] sliced"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The second assignment statement binds the name t2 to a tuple that contains the tuple to which t1 is bound and the floating point number 3.25. This is possible because a tuple, like everything else in Python, is an object, so tuples can contain tuples.\n",
    "Therefore, the first print statement produces the output,\n",
    "```python\n",
    "((1, 'two', 3), 3.25)\n",
    "```\n",
    "\n",
    "The second print statement prints the value generated by concatenating the values bound to t1 and t2, which is a tuple with five elements. It produces the output\n",
    "```python\n",
    "(1, 'two', 3, (1, 'two', 3), 3.25)\n",
    "```\n",
    "The next statement selects and prints the fourth element of the concatenated tuple (as `always` in Python, `indexing starts at 0`), and the statement after that creates and prints a slice of that tuple, producing the output\n",
    "```python\n",
    "(1, 'two', 3)\n",
    "(3, (1, 'two', 3))\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.1 Tuples are <b style=\"color:blue\">immutable<b>\n",
    "    \n",
    "The tuples cannot be modified after they are created.\n",
    " \n",
    "if you try to modify one of the elements of the tuple, you get an error:\n",
    "\n",
    "```python\n",
    "TypeError: 'tuple' object does not support item assignment\n",
    "```    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'tuple' object does not support item assignment",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-10-55b0faf81b40>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[0mt1\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'two'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mt1\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'A'\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: 'tuple' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "t1 = (1, 'two', 3)\n",
    "t1[0]='A'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Because tuples are immutable, you can’t modify the elements. \n",
    "\n",
    "You can replace one tuple with another,\n",
    "\n",
    "This statement makes a **new tuple** and then makes `t1` refer to it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('A', 'two', 3)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t1 = ('A',) + t1[1:]\n",
    "t1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###  1.2 Iterate over the elements of a tuple\n",
    "\n",
    "`for` e  in seq\n",
    "\n",
    "A <b  style=\"color:blue\">for</b> statement can be used to <b style=\"color:blue\">iterate over the elements</b> of a `tuple`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "two\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "t1 = (1, 'two', 3)\n",
    "for e in t1:\n",
    "    print(e) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "can only concatenate tuple (not \"int\") to tuple",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-17-40246dfa8a47>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m     12\u001b[0m \u001b[0mt1\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'two'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     13\u001b[0m \u001b[0mt2\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 14\u001b[1;33m \u001b[0mresult\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mintersect\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mt1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mt2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     15\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m<ipython-input-17-40246dfa8a47>\u001b[0m in \u001b[0;36mintersect\u001b[1;34m(t1, t2)\u001b[0m\n\u001b[0;32m      7\u001b[0m     \u001b[1;32mfor\u001b[0m \u001b[0me\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mt1\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      8\u001b[0m         \u001b[1;32mif\u001b[0m \u001b[0me\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mt2\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 9\u001b[1;33m             \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mresult\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0me\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     10\u001b[0m     \u001b[1;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     11\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mTypeError\u001b[0m: can only concatenate tuple (not \"int\") to tuple"
     ]
    }
   ],
   "source": [
    "def intersect(t1, t2):\n",
    "    \"\"\"Assumes t1 and t2 are tuples\n",
    "        Returns a tuple containing elements that are in\n",
    "        both t1 and t2\n",
    "    \"\"\"\n",
    "    result = ()\n",
    "    for e in t1:\n",
    "        if e in t2:\n",
    "            result = result + (e,)\n",
    "    return result\n",
    "\n",
    "t1 = (1,2, 'two', 3,4)\n",
    "t2 = (1,4)\n",
    "result=intersect(t1, t2)\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.3 Operators and Functions on tuples\n",
    "\n",
    "You can operate on tuples using (supposing that tup is a tuple):\n",
    "    \n",
    "* built-in functions such as `len(tup)`;\n",
    "\n",
    "* built-in functions for tuple of numbers such as `max(tup), min(tup) and sum(tup)`\n",
    "\n",
    "Tuple methods: \n",
    "\n",
    "* `count(e)` : counts the number of occurrences of a value e\n",
    "\n",
    "* `index(e)`: return the index of the first  occurrences of e in tup,or error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tup=(1,2,2,3)\n",
    "len(tup)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3, 1, 8)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "max(tup), min(tup), sum(tup)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tup.count(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "tuple.index(x): x not in tuple",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-23-99187f8f8094>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mtup\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m: tuple.index(x): x not in tuple"
     ]
    }
   ],
   "source": [
    "tup.index(4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###  1.4 Sequence unpacking\n",
    "\n",
    "If you know the <b>length of a sequence</b> (e.g., a tuple or a string),\n",
    "\n",
    "it can be convenient to use Python’s <b>multiple assignment</b> statement to extract the individual elements.\n",
    "\n",
    "* **Sequence unpacking**\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x= 3  y= 4  z= 5\n"
     ]
    }
   ],
   "source": [
    "# Sequence unpacking\n",
    "x, y ,z= (3, 4,5)\n",
    "print('x=',x,' y=',y,' z=',z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a= x  b= y  c= z\n"
     ]
    }
   ],
   "source": [
    "a, b, c = 'xyz'\n",
    "print('a=',a,' b=',b,' c=',c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.7"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "165px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  },
  "widgets": {
   "state": {},
   "version": "1.1.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
